﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using BBMS.DLL.Base;
using System.IO;
using ExcelLibrary.CompoundDocumentFormat;
using ExcelLibrary.SpreadSheet;
using ExcelLibrary.BinaryFileFormat;
using BBMS.FrontEnd.Constant;
using BBMS.DLL.DataContract;


namespace BBMS.DLL.Forms.Base
{
    public partial class FrmFilterBase : Form
    {
        public static readonly string FunctionKey = "FrmFilterBase";
        protected virtual string GetFunctionKey() { return "FrmFilterBase"; }
        protected FilterParams fParams = new FilterParams();
        protected virtual ObjectBase GetObjectBase() { return null; }
        public FrmFilterBase()
        {
            InitializeComponent();
            this.Font = SystemFonts.MessageBoxFont;
            GenColHeaders();
            InitControls();

        }
        protected virtual void ReColorItems()
        {
            for (int i = 0; i < lvList.Items.Count; i++)
            {
                ListViewItem it = lvList.Items[i];
                if (i % 2 != 0) it.BackColor = System.Drawing.Color.WhiteSmoke;
                //else it.BackColor = System.Drawing.Color.Beige;
                it.UseItemStyleForSubItems = true;
            }
        }
        protected virtual void ListObject()
        {
            lvList.Items.Clear();
            ObjectBase objectBase = GetObjectBase();
            if (objectBase != null)
            {
                int curPage;
                int totalPage;
                ArrayList arObjs = objectBase.GetObjectByPage(out curPage, out totalPage, fParams);
                fParams.CurrentPage = curPage;
                fParams.TotalPage = totalPage;
                txCbxPage.Items.Clear();
                for (int i = 0; i < fParams.TotalPage; i++)
                    txCbxPage.Items.Add(i + 1);

                if (txCbxPage.Items.Count > 0) txCbxPage.SelectedIndex = fParams.CurrentPage - 1;

                if (arObjs == null || arObjs.Count == 0)
                    MessageBox.Show("Không có bản ghi nào trong cơ sở dữ liệu.");
                else
                {
                    foreach (BBMS.DLL.Base.ObjectBase obj in arObjs)
                        AddNewObjectToList(obj);
                }
                ReColorItems();
            }
        }

        protected virtual void GenColHeaders()
        {
        }

        protected virtual void InitControls()
        {
            foreach (ToolStripItem it in tsMenu.Items)
            {
                if (it is ToolStripButton)
                    it.Enabled = false;
            }
            try
            {
                string str = this.GetFunctionKey();

                tsBtnExport.Enabled = false;
                tsBtnFind.Enabled = false;
                tsBtnRefresh.Enabled = false;
                tsBtnGo.Enabled = false;
                tsBtnNew.Enabled = false;
                tsBtnImportFile.Enabled = false;
                tsBtnImport.Enabled = false;
                tsBtnEdit.Enabled = false;
                tsBtnDel.Enabled = false;

                if (BBMS.DLL.Base.Config.CurUser.HaveRole(Role.Read, str))
                {
                    tsBtnExport.Enabled = true;
                    tsBtnFind.Enabled = true;
                    tsBtnRefresh.Enabled = true;
                    tsBtnGo.Enabled = true;
                }
                if (BBMS.DLL.Base.Config.CurUser.HaveRole(Role.Add, str))
                {
                    tsBtnNew.Enabled = true;
                    tsBtnImportFile.Enabled = true;
                    tsBtnImport.Enabled = true;
                }

                if (BBMS.DLL.Base.Config.CurUser.HaveRole(Role.Delete, str))
                {
                    tsBtnDel.Enabled = true;
                }

                if (BBMS.DLL.Base.Config.CurUser.HaveRole(Role.Edit, str))
                {
                    tsBtnEdit.Enabled = true;
                }
            }
            catch
            {
            }
        }

        protected virtual void OnNewClick()
        {
            if (Config.CurUser.HaveRole(Role.Add, this.GetFunctionKey()))
            {
                FrmEditBase frm = CreateEditForm(null);
                frm.OnAddedNewObject += new AddedNewObject(AddNewObjectToListBase);
                frm.OnUpdatedObject += new UpdatedObject(UpdateObjectToList);
                frm.ShowDialog();
            }
            else SystemHelper.DialogExclamation("Bạn không có quyền thực hiện tính năng này.");
        }



        private void tsBtnNew_Click(object sender, EventArgs e)
        {
            OnNewClick();
        }

        protected virtual void OnEditClick()
        {
            if (lvList.SelectedItems.Count > 0)
            {
                if (Config.CurUser.HaveRole(Role.Add, this.GetFunctionKey()))
                {
                    FrmEditBase frm = CreateEditForm(lvList.SelectedItems[0].Tag as ObjectBase);
                    frm.OnAddedNewObject += new AddedNewObject(AddNewObjectToListBase);
                    frm.OnUpdatedObject += new UpdatedObject(UpdateObjectToList);
                    frm.ShowDialog();
                }
                else SystemHelper.DialogExclamation("Bạn không có quyền thực hiện tính năng này.");
            }
            else SystemHelper.DialogInfo("Bạn hãy chọn một bản ghi để sửa.");
        }

        private void tsBtnEdit_Click(object sender, EventArgs e)
        {
            OnEditClick();
        }

        protected virtual void UpdateFilterParams()
        {
        }

        protected virtual void OnDelClick()
        {
            if (lvList.SelectedItems.Count > 0)
            {
                if (Config.CurUser.HaveRole(Role.Delete, this.GetFunctionKey()))
                {
                    if (SystemHelper.DialogQuestion("Bạn có muốn xóa bản ghi?") == DialogResult.Yes)
                    {
                        ObjectBase obj = lvList.SelectedItems[0].Tag as ObjectBase;
                        string msg = obj.Delete();
                        if (msg != "")
                            MessageBox.Show(msg);
                        else
                        {
                            lvList.Items.Remove(lvList.SelectedItems[0]);
                            SystemHelper.DialogInfo("Đã xóa bản ghi thành công.");
                            ReColorItems();
                        }
                    }

                }
                else SystemHelper.DialogExclamation("Bạn không có quyền thực hiện tính năng này.");
            }
            else SystemHelper.DialogInfo("Bạn hãy chọn một bản ghi để xóa.");
        }

        private void tsBtnDel_Click(object sender, EventArgs e)
        {
            OnDelClick();
        }

        protected virtual void OnFindClick()
        {
            UpdateFilterParams();
            ListObject();
        }

        private void tsBtnFind_Click(object sender, EventArgs e)
        {
            OnFindClick();
        }

        protected virtual void OnRefreshClick()
        {
            ListObject();
        }

        protected virtual void OnSearchClick()
        {
            ListObject();
        }

        protected virtual void AddNewObjectToListBase(ObjectBase obj)
        {
            AddNewObjectToList(obj);
            ReColorItems();
        }
        protected virtual void AddNewObjectToList(ObjectBase obj) { }
        protected virtual void UpdateObjectToList(ObjectBase obj) { }

        private void tsBtnRefresh_Click(object sender, EventArgs e)
        {
            fParams = new FilterParams();
            OnRefreshClick();
        }
        protected virtual void OnGoClick()
        {
            int page = txCbxPage.SelectedIndex;
            if (fParams.CurrentPage != page + 1)
            {
                fParams.CurrentPage = page + 1;
                ListObject();
            }
        }
        protected virtual FrmEditBase CreateEditForm(ObjectBase obj)
        {
            return null;
        }
        private void tsBtnGo_Click(object sender, EventArgs e)
        {
            OnGoClick();
        }

        protected virtual void OnImportClick()
        {
            FrmImportBase frmNew = new FrmImportBase();
            DialogResult dr = frmNew.ShowDialog();
            if (dr == DialogResult.OK)
            {
                CompoundDocument doc = CompoundDocument.Open(frmNew.FilePath.ToString().Trim()); 

                byte[] bookdata = doc.GetStreamData("Workbook");
                if (bookdata == null) return;
                Workbook book = WorkbookDecoder.Decode(new MemoryStream(bookdata));


                foreach (Worksheet sheet in book.Worksheets)
                {
                    TabPage sheetPage = new TabPage(sheet.Name);
                    if (sheet.Cells.Rows.Count <= 1) return;
                    

                    //List<ObjectBase> objList = GetImportedList(sheet);
                    ArrayList objList = null;
                    try
                    {
                        objList = GetImportedList(sheet);
                    }
                    catch { };
                    if (objList != null)
                    {
                        if (objList.Count < sheet.Cells.Rows.Count)
                        {
                            MessageBox.Show(null, "Lỗi file import, kiểm tra lại file, lỗi ở dòng: " + objList.Count, "Thông báo");
                            return;
                        }
                        String result = ImportList.ImportArrayList(objList, frmNew.ImportMode);
                        MessageBox.Show(null, result, "Thông báo");
                        OnRefreshClick();
                    }
                    //for (int i = 1; i < sheet.Cells.Rows.Count; i++)
                    // {
                        // get cell and value here
                        //Cell cell = sheet.Cells[i, 0];
                        //cell.Value
                        //Cell cell = sheet.Cells[i, 1];
                        //Cell cell = sheet.Cells[i, 2];
                        //Cell cell = sheet.Cells[i, 3]; 
                        //....


                    //}
                }
            }
        }

        //protected virtual List<ObjectBase> GetImportedList(Worksheet sheet) { return null; }
        protected virtual ArrayList GetImportedList(Worksheet sheet) { return null; }


        private void LoadExcelSheets(string fileName,ImportMode importMode)
        {

            CompoundDocument doc = CompoundDocument.Open(fileName); ;

            byte[] bookdata = doc.GetStreamData("Workbook");
            if (bookdata == null) return;
            Workbook book = WorkbookDecoder.Decode(new MemoryStream(bookdata));


            foreach (Worksheet sheet in book.Worksheets)
            {
                TabPage sheetPage = new TabPage(sheet.Name);
                if (sheet.Cells.Rows.Count <= 1) return;
                for (int i = 1; i < sheet.Cells.Rows.Count; i++)
                {
                    // get cell and value here
                    //Cell cell = sheet.Cells[i, 0];
                    //cell.Value
                    //Cell cell = sheet.Cells[i, 1];
                    //Cell cell = sheet.Cells[i, 2];
                    //Cell cell = sheet.Cells[i, 3]; 
                    //....


                }
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            try
            {
                switch (keyData)
                {
                    case Keys.F6:
                        OnNewClick();
                        break;
                    case Keys.F7:
                        OnEditClick();
                        break;
                    case Keys.Delete:
                        OnDelClick();
                        break;
                    case Keys.Escape:
                        this.Close();
                        break;
                    case Keys.F5:
                        OnRefreshClick();
                        break;
                    default:
                        break;
                }
            }
            catch
            {
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void tsBtnImport_Click(object sender, EventArgs e)
        {
            OnImportClick();
        }

        protected virtual void OnExportClick()
        {
            
        }
        private void tsBtnExport_Click(object sender, EventArgs e)
        {
            OnImportSampleFileClick();
        }

        private void tsBtnImportFile_Click(object sender, EventArgs e)
        {
            OnImportSampleFileClick();
        }

        /*protected virtual void OnImportSampleFileClick()
        {
            SaveFileDialog SaveDialog1 = new SaveFileDialog();
            SaveDialog1.Filter = "Excel 97/2003 Files|*.xls|Excel 2007 Files|*.xlsx|All Files|*.*";
            SaveDialog1.Title = "Chọn đường dẫn lưu tệp mẫu định dạng .xls";
            //SaveDialog1.InitialDirectory = @"C:\";
            SaveDialog1.FileName = "sample";
            if (SaveDialog1.ShowDialog() == DialogResult.OK)
            {
                String filePath = SaveDialog1.FileName;
                if (filePath!= "")
                {
                    ArrayList ar = this.GenSampleData();
                    if (ar != null)
                    {
                        XlsFile xls = new XlsFile(true);
                        xls.NewFile(1);
                        
                        for (int i = 0; i < ar.Count; i++)
                        {
                            if (ar[i] is string[])
                            {
                                string[] strs = ar[i] as string[];
                                for (int j = 0; j < strs.Length; j++)
                                    xls.SetCellValue(i + 1, j + 1, strs[j]);
                            }
                            else if (ar[i] is int[])
                            {
                                int[] colwidths = ar[i] as int[];
                                for (int j = 0; j < colwidths.Length; j++)
                                {
                                    xls.SetColWidth(j + 1, colwidths[j]);
                                    //System.Diagnostics.Debug.WriteLine(string.Format(" {0} - {1} ", j + 1, colwidths[j]));
                                }
                            }
                            
                        }
                        xls.Save(filePath, FlexCel.Core.TFileFormats.Xls);
                        MessageBox.Show("Export tệp mẫu thành công!");
                    }
                }
            }
        }*/

        protected virtual void OnImportSampleFileClick()
        {
            SaveFileDialog SaveDialog1 = new SaveFileDialog();
            SaveDialog1.Filter = "Excel 97/2003 Files|*.xls|All Files|*.*";
            SaveDialog1.Title = "Chọn đường dẫn lưu tệp mẫu định dạng .xls";
            //SaveDialog1.InitialDirectory = @"C:\";
            SaveDialog1.FileName = "sample";
            if (SaveDialog1.ShowDialog() == DialogResult.OK)
            {
                String filePath = SaveDialog1.FileName;
                if (filePath != "")
                {
                    ArrayList ar = this.GenSampleData();
                    if (ar != null)
                    {
                        Workbook workbook = new Workbook();
                        Worksheet worksheet = new Worksheet("First Sheet");
                        for (int i = 0; i < ar.Count; i++)
                        {
                            if (ar[i] is string[])
                            {
                                string[] strs = ar[i] as string[];
                                for (int j = 0; j < strs.Length; j++)
                                    worksheet.Cells[i, j] = new Cell(strs[j]);
                            }
                            else if (ar[i] is int[])
                            {
                                int[] colwidths = ar[i] as int[];
                                for (int j = 0; j < colwidths.Length; j++)
                                {
                                    worksheet.Cells.ColumnWidth[0, Convert.ToUInt16(j)] = Convert.ToUInt16(colwidths[j]);
                                    //System.Diagnostics.Debug.WriteLine(string.Format(" {0} - {1} ", j + 1, colwidths[j]));
                                }
                            }

                        }
                        workbook.Worksheets.Add(worksheet);
                        workbook.Save(filePath);
                        MessageBox.Show("Export tệp mẫu thành công!");
                    }
                }
            }
        }

        protected virtual ArrayList GenSampleData()
        {
            return null;
        }

        private void FrmFilterBase_Load(object sender, EventArgs e)
        {
            MethodInvoker updateListAsync = delegate
            {
                ListObject();
            };
            if (lvList.InvokeRequired || tsMenu.InvokeRequired)
            {
                lvList.Invoke(updateListAsync);
                tsMenu.Invoke(updateListAsync);
            }
            else
                updateListAsync();
            this.WindowState = FormWindowState.Maximized;

        }

        private void lvList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvList.SelectedItems.Count > 0)
            {
                if (Config.CurUser.HaveRole(Role.Delete, GetFunctionKey()))
                    tsBtnDel.Enabled = true;
                if (Config.CurUser.HaveRole(Role.Edit, GetFunctionKey()))
                    tsBtnEdit.Enabled = true;
            }
            else
            {
                tsBtnDel.Enabled = false;
                tsBtnEdit.Enabled = false;
            }
        }

        private void lvList_DoubleClick(object sender, EventArgs e)
        {
            if (lvList.SelectedItems.Count > 0)
            {
                if (Config.CurUser.HaveRole(Role.Read, GetFunctionKey()))
                    OnEditClick();
            }
        }
    }
}
